package com.guchenbo.erp.inventory.service.impl;

import com.baomidou.mybatisplus.core.conditions.query.QueryWrapper;
import com.baomidou.mybatisplus.extension.service.impl.ServiceImpl;
import com.guchenbo.erp.inventory.dto.InboundRequest;
import com.guchenbo.erp.inventory.entity.InventoryCost;
import com.guchenbo.erp.inventory.mapper.InventoryCostMapper;
import com.guchenbo.erp.inventory.service.InventoryCostService;
import org.springframework.stereotype.Service;

import java.math.BigDecimal;
import java.math.RoundingMode;

/**
 * <p>
 * 库存成本表 服务实现类
 * </p>
 *
 * @author guchenbo
 * @since 2025-07-12
 */
@Service
public class InventoryCostServiceImpl extends ServiceImpl<InventoryCostMapper, InventoryCost> implements InventoryCostService {

    @Override
    public void inbound(InboundRequest request) {
        InventoryCost cost = findOrCreate(request);
        // 加权平均法计算新成本
        BigDecimal oldQty = cost.getQuantity();
        BigDecimal oldTotal = cost.getCostPrice().multiply(oldQty);
        BigDecimal newTotal = request.getUnitPrice().multiply(request.getQuantity());

        BigDecimal newQty = oldQty.add(request.getQuantity());
        BigDecimal newPrice = oldQty.compareTo(BigDecimal.ZERO) == 0 ? request.getUnitPrice()
                        : oldTotal.add(newTotal).divide(newQty, 4, RoundingMode.HALF_UP);

        cost.setQuantity(newQty);
        cost.setCostPrice(newPrice);
        this.update(cost);
    }

    private InventoryCost findOrCreate(InboundRequest request) {
        QueryWrapper<InventoryCost> queryWrapper = new QueryWrapper<>();
        queryWrapper.lambda().eq(InventoryCost::getProductId, request.getProductId())
                        .eq(InventoryCost::getWarehouseId, request.getWarehouseId());
        InventoryCost inventoryCost = this.getOne(queryWrapper);
        if (inventoryCost == null) {
            inventoryCost = new InventoryCost();
            inventoryCost.setProductId(request.getProductId());
            inventoryCost.setWarehouseId(request.getWarehouseId());
            this.save(inventoryCost);
        }
        return inventoryCost;
    }
}
